﻿namespace Kestrel_Demo
{
    using System;
    using System.IO;
    using System.Net;
    using System.Text;

    internal class HttpServerTool
    {
        private HttpListener httpListener;

        private Action<HttpListenerRequest, HttpListenerResponse> httpHandle;

        private HttpServerTool()
        {
        }

        public static HttpListener GetNewInstance(int port, Action<HttpListenerRequest, HttpListenerResponse> httpHandle = default)
        {
            var instance = new HttpServerTool();

            return instance.InitializeHttpServer(port, httpHandle ?? new Action<HttpListenerRequest, HttpListenerResponse>(DefaultHandle));
        }

        private HttpListener InitializeHttpServer(int port, Action<HttpListenerRequest, HttpListenerResponse> httpHandle)
        {
            httpListener = new HttpListener();

            httpListener.Prefixes.Add($"http://*:{port}/");

            httpListener.Start();

            httpListener.BeginGetContext(new AsyncCallback(OnRequest), httpListener);

            this.httpHandle = httpHandle;

            return httpListener;
        }

        private void OnRequest(IAsyncResult asyncResult)
        {
            try
            {
                var context = httpListener.EndGetContext(asyncResult);

                var response = context.Response;

                var request = context.Request;

                response.Headers.Add("Content-type", "text/html;charset=UTF-8");
                response.ContentEncoding = Encoding.UTF8;

                // 后台跨域请求，通常设置为配置文件
                response.AppendHeader("Access-Control-Allow-Origin", "*");

                // 后台跨域请求
                response.AppendHeader("Access-Control-Allow-Credentials", "true");

                // 后台跨域请求，通常设置为配置文件
                response.AppendHeader("Server", "MyIIS");

                // 允许的方法
                response.Headers.Add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");

                // 对于预检请求，直接返回200状态码
                if (request.HttpMethod == "OPTIONS")
                {
                    context.Response.AppendHeader("Access-Control-Allow-Headers", "Authorization,Content-Type,Accept,Origin,User-Agent,DNT,Cache-Control,X-Mx-ReqToken,X-Requested-With");
                    context.Response.AppendHeader("Access-Control-Max-Age", "86400");

                    response.StatusCode = 200;

                    response.Close();
                    response.Abort();
                }
                else
                {
                    try
                    {
                        httpHandle?.Invoke(request, response);
                    }
                    catch (Exception _)
                    {
                    }
                    finally
                    {
                        response.Close();
                        response.Abort();
                    }
                }

                // 继续等待下一个请求
                httpListener.BeginGetContext(new AsyncCallback(OnRequest), httpListener);
            }
            catch (Exception ex)
            {
                //Show($"Error: {ex.Message}", "HTTP Server Error");
            }
        }

        private static void DefaultHandle(
            HttpListenerRequest request,
            HttpListenerResponse response)
        {
            if (request.HttpMethod == "POST")
            {
                // 读取请求体中的数据
                using (var streamReader = new StreamReader(request.InputStream, request.ContentEncoding))
                {
                    var requestBody = streamReader.ReadToEnd();

                    // 构造响应
                    var responseString = $"Received POST data: {requestBody}";

                    response.StatusCode = 200;

                    var buffer = Encoding.UTF8.GetBytes(responseString);

                    response.ContentLength64 = buffer.Length;

                    using (var output = response.OutputStream)
                    {
                        output.Write(buffer, 0, buffer.Length);
                    }
                }
            }
            else
            {
                // 对于其他请求方法，返回简单的响应
                var responseString = "Hello, World!";

                var buffer = Encoding.UTF8.GetBytes(responseString);

                response.ContentLength64 = buffer.Length;

                using (var output = response.OutputStream)
                {
                    output.Write(buffer, 0, buffer.Length);
                }
            }
        }
    }
}
